package com.zhilei.mq;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PreDestroy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 实现spring的多线程配置类
 *
 * @author 志磊
 * @data 2024-09-11
 */
@Slf4j
@Configuration
public class RabbitMqConfig {

    private final ExecutorService executor = Executors.newFixedThreadPool(100);

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setTaskExecutor(executor);

        // 可以设置消息确认回调和返回回调
        // 设置消息的可靠性传递,确认成功的回调
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             * 消息确认的回调函数
             * @param correlationData  相关联的数据
             * @param b 交换机成功接收消息的回调
             * @param s 失败的原因
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean b, String s) {
                log.info("消息进入确认的回调！");
                if (b) {
                    log.info("消息成功的原因是：{}", s);
                    System.out.println("消息[" + correlationData.getId() + "] 确认成功");
                } else {
                    log.info("消息失败的原因是：{}", s);
                    System.err.println("消息[" + correlationData.getId() + "] 确认失败: " + s);
                }
                log.info("消息完成确认的回调！");
            }
        });

        // 设置返回的回调
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            /**
             * 执行返回的回调
             * @param returnedMessage
             */
            @Override
            public void returnedMessage(ReturnedMessage returnedMessage) {
                log.info("消息进入返回的回调！");
                log.info("消息被拒绝：{}", returnedMessage);
                log.info("消息完成返回的回调！");
            }
        });

        return rabbitTemplate;
    }

    /**
     * 关闭spring容器时销毁线程
     */
    @PreDestroy
    public void destroy() {
        executor.shutdown();
    }
}
